﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing.WebControls;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.WebPartPages;
using System.Diagnostics.CodeAnalysis;

namespace lcqwp
{
    /// <summary>
    /// The <see>LocalizableContentByQueryWebPart</see> is a specialization of the 
    /// built-in MOSS Content by Query Web Part. The class extends the 
    /// base class web part by allowing resource file look up from XSLT,
    /// GUI based selection of header and item XSL style files and choose 
    /// additional fields to be fetched form the source list.
    /// </summary>
    /// <remarks>
    /// Use this web part as a regular Content by Query WebPart. To enable resource file
    /// look up, set the ResourceFilename property to the desired resource file, without 
    /// the file extension. The resource file has to be placed in the App_GlobalResources
    /// folder of the MOSS web application. The entered filename shall be prefixed with 
    /// "Resources.". The namespace to be added to your XSLT to include the resource file 
    /// look-up functionality is by default 
    /// <code>http://lcqwp/2009/LocalizableCQWP</code>. This 
    /// can be changed by setting the LocalizationExtensionNamespace property on the 
    /// web part instance.<br/><br/>
    /// Here is how the extension is defined in the XSLT:
    /// <code>
    /// <![CDATA[<xsl:stylesheet version="1.0" ... xmlns:ecqwp="http://lcqwp/2009/LocalizableCQWP">...</xsl:stylesheet>]]>
    /// </code>
    /// <br/><br/>
    /// Here is an example of a call to insert a resource value:
    /// <code>
    /// <![CDATA[<xsl:value-of select="lcqwp:GetLabel('listsyndication_rsschannel_channeltitle','Title Default')"/>]]>
    /// </code>
    /// </remarks>
    [ToolboxData("<{0}:LocalizableContentByQueryWebPart runat=server></{0}:LocalizableContentByQueryWebPart>")]
    [XmlRoot(Namespace = "lcqwp")]
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
    [AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel = true)]
    [Guid("548EDE1E-06A5-4e7b-9302-A1CF72F844E8")]
    [CLSCompliant(false)]
    public class LocalizableContentByQueryWebPart : ContentByQueryWebPart
    {
        private const string Empty = "";
        private const string DefaultNamespace = "http://lcqwp/2009/LocalizableCQWP";
        private const string DefaultAssemblyName = "App_GlobalResources";
        private string _resourceFilename = Empty;
        private string _resourceAssemblyName = DefaultAssemblyName;
        private string _localizationExtensionNamespace = DefaultNamespace;

        private ToolPart _toolPart;

        /// <summary>
        /// Use this method to change the XSL argument list generated by the base
        /// class before it is passed to the XSL transform. <br/><br/>
        /// The LocalizableContentByQueryWebPart extends the base class behaivor by adding a namespace 
        /// to be matched with a .NET/C# class instance for
        /// localization calls from XSLT commands.
        /// </summary>
        /// <param name="argList">Argument list generated by the base class.</param>
        protected override void ModifyXsltArgumentList(ArgumentClassWrapper argList)
        {
            CultureInfo currentCulture = SPContext.Current.Web.GetCurrentCulture();

            ResourceLookUpLibrary resourceLookUpLibrary =
                new ResourceLookUpLibrary(_resourceAssemblyName, _resourceFilename, currentCulture);
            argList.AddExtensionObject(_localizationExtensionNamespace, resourceLookUpLibrary);
            base.ModifyXsltArgumentList(argList);
        }

        /// <summary>
        /// The name of the resource file to be used in the 
        /// XSL extension code
        /// </summary>
        [WebBrowsable(false)]
        [WebPartStorage(Storage.Shared)]
        [Personalizable(true)]
        [DefaultValue(Empty)]
        [Category("Localization")]
        [WebDisplayName("Resource filename")]
        [WebDescription("Resource filename")]
        public string ResourceFilename
        {
            get
            {
                return _resourceFilename;
            }
            set
            {
                _resourceFilename = value;
            }
        }

        /// <summary>
        /// The namespace to be used for the extension 
        /// to retrieve resource labels
        /// </summary>
        [WebBrowsable(false)]
        [WebPartStorage(Storage.Shared)]
        [Personalizable(PersonalizationScope.Shared)]
        [DefaultValue(DefaultNamespace)]
        public string LocalizationExtensionNamespace
        {
            get
            {
                return _localizationExtensionNamespace;
            }
            set
            {
                _localizationExtensionNamespace = value;
            }
        }

        /// <summary>
        /// The comma separated list of field names to be included
        /// in the query result other than the default fields (ID, Title, etc).
        /// </summary>
        [WebBrowsable(false)]
        [WebPartStorage(Storage.Shared)]
        [Personalizable(PersonalizationScope.Shared)]
        [Category("Localization")]
        [WebDisplayName("Extra Fields")]
        [WebDescription("Additional fields to be fetched in the query")]
        public string ExtraFields
        {
            get
            {
                string fields = base.CommonViewFields;
                return fields;
            }
            set
            {
                base.CommonViewFields = value;
            }
        }

        /// <summary>
        /// Return the tool panes that configure this LocalizableContentQueryWebPart object.
        /// </summary>
        /// <returns>the tool panes that configure this LocalizableContentQueryWebPart object</returns>
        [SharePointPermission(SecurityAction.Demand, ObjectModel = true)]
        public override ToolPart[] GetToolParts()
        {
            ToolPart[] baseToolParts = base.GetToolParts();
            List<ToolPart> list = new List<ToolPart>(baseToolParts);
            list.Add(new LocalizableContentByQueryWebPartToolPart());
            foreach (ToolPart toolPart in list)
            {
                if (toolPart.GetType() == typeof(ContentByQueryToolPart))
                {
                    _toolPart = toolPart;
                }
            }
            return list.ToArray();
        }

        /// <summary>
        /// Sets the title of the tool part
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (_toolPart != null)
                _toolPart.Title = "Localizable Content Query Tool Part";
        }
    }
}
